import { LayaGL } from "../../../layagl/LayaGL";
import { IIndexBuffer } from "../../../RenderDriver/DriverDesign/RenderDevice/IIndexBuffer";
import { IVertexBuffer } from "../../../RenderDriver/DriverDesign/RenderDevice/IVertexBuffer";
import { ShaderDataType } from "../../../RenderDriver/DriverDesign/RenderDevice/ShaderData";
import { BufferUsage } from "../../../RenderEngine/RenderEnum/BufferTargetType";
import { Shader3D, ShaderFeatureType } from "../../../RenderEngine/RenderShader/Shader3D";
import { SubShader } from "../../../RenderEngine/RenderShader/SubShader";
import { VertexDeclaration } from "../../../RenderEngine/VertexDeclaration";
import { VertexElement } from "../../../renders/VertexElement";
import { VertexElementFormat } from "../../../renders/VertexElementFormat";
import PhysicsLineFs from "./PhysicsLine.fs";
import PhysicsLineVs from "./PhysicsLine.vs";

export class PhysicsLineShader {
    static LINEWIDTH: number;
    static DASHED: number;
    static TILINGOFFSET: number;
    static linePoisitionDesc: VertexDeclaration;
    static lineLengthDesc: VertexDeclaration;

    /**
     * @internal
     */
    static _vbs: IVertexBuffer;


    /**
     * @internal
     */
    static _ibs: IIndexBuffer;
    private static _isInit: boolean = false;
    static __init__() {
        if (PhysicsLineShader._isInit) return;
        PhysicsLineShader._isInit = true;
        let attributeMap: { [name: string]: [number, ShaderDataType] } = {
            'a_position': [0, ShaderDataType.Vector3],
            'a_linePos': [2, ShaderDataType.Vector4],
            "a_linelength": [3, ShaderDataType.Float],
        };
        let uniformMap = {
            u_lineWidth: ShaderDataType.Float,
            u_TilingOffset: ShaderDataType.Vector4,
        };
        let shader = Shader3D.add("PhysicsLineShader", true, false);
        shader.shaderType = ShaderFeatureType.Default;
        let subShader = new SubShader(attributeMap, uniformMap, {});
        shader.addSubShader(subShader);
        let forwardPass = subShader.addShaderPass(PhysicsLineVs, PhysicsLineFs);

        PhysicsLineShader.LINEWIDTH = Shader3D.propertyNameToID("u_lineWidth");
        PhysicsLineShader.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset");

        let vertexs: Float32Array = new Float32Array([
            -0.5, -0.5, 0,
            0.5, -0.5, 0,
            0.5, 0.5, 0,
            - 0.5, 0.5, 0]);
        let index: Uint16Array = new Uint16Array([0, 1, 2, 0, 2, 3]);
        var declaration = new VertexDeclaration(12, [
            new VertexElement(0, VertexElementFormat.Vector3, 0),
        ]);
        let vertex = PhysicsLineShader._vbs = LayaGL.renderDeviceFactory.createVertexBuffer(BufferUsage.Dynamic);
        vertex.vertexDeclaration = declaration;
        vertex.instanceBuffer = false;
        vertex.setDataLength(vertexs.byteLength);
        vertex.setData(vertexs.buffer, 0, 0, vertexs.byteLength);

        let ibs = PhysicsLineShader._ibs = LayaGL.renderDeviceFactory.createIndexBuffer(BufferUsage.Dynamic);
        ibs._setIndexDataLength(index.buffer.byteLength);
        ibs._setIndexData(index, 0);

        PhysicsLineShader.linePoisitionDesc = new VertexDeclaration(16, [
            new VertexElement(0, VertexElementFormat.Vector4, 2),
        ]);

        PhysicsLineShader.lineLengthDesc = new VertexDeclaration(4, [
            new VertexElement(0, VertexElementFormat.Single, 3),
        ]);

    }
}
